package icu.zhhll.util.collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 集合工具类
 *
 * @author zh
 * @date 2023/9/7 21:50
 */
public class CollectionUtils {

    /**
     * 集合比较
     *
     * @param list1
     * @param list2
     * @return
     */
    public static boolean listEquals(List<? extends Comparable> list1, List<? extends Comparable> list2) {
        if (list1 == null && list2 == null) {
            return true;
        }
        if (list1 == null || list2 == null) {
            return false;
        }
        if (list1.size() != list2.size()) {
            return false;
        }

        Collections.sort(list1);
        Collections.sort(list2);

        for (int i = 0; i < list1.size(); i++) {
            if (!list1.get(i).equals(list2.get(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取集合前k条数据
     *
     * @param list 对象需要实现Comparable接口
     * @param k
     * @return
     */
    public static List<? extends Comparable> topK(List<? extends Comparable> list, int k) {
        if (list == null || list.size() == 0) {
            throw new RuntimeException("集合不可为空");
        }

        return list.stream().sorted().limit(k).collect(Collectors.toList());
    }

    /**
     * 获取集合前k条数据
     *
     * @param list
     * @param comparator 比较器
     * @param k
     * @param <T>
     * @return
     */
    public static <T> List<T> topK(List<T> list,
                                   Comparator<T> comparator,
                                   int k) {
        if (list == null || list.size() == 0) {
            throw new RuntimeException("集合不可为空");
        }

        return list.stream().sorted(comparator).limit(k).collect(Collectors.toList());
    }

    /**
     * 差集  list1 - list2
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> diff(List<T> list1, List<T> list2) {
        if (list1 == null || list1.size() == 0) {
            return new ArrayList<>();
        }
        if (list2 == null || list2.size() == 0) {
            return list1;
        }
        return list1.stream().filter(
                item -> !list2.contains(item)
        ).collect(Collectors.toList());
    }


    /**
     * 交集
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> inter(List<T> list1, List<T> list2) {
        if (list1 == null || list1.size() == 0) {
            return new ArrayList<>();
        }
        if (list2 == null || list2.size() == 0) {
            return new ArrayList<>();
        }
        return list1.stream().filter(
                list2::contains
        ).collect(Collectors.toList());
    }

    /**
     * 并集
     *
     * @param list1
     * @param list2
     * @param <T>
     * @return
     */
    public static <T> List<T> union(List<T> list1, List<T> list2) {
        return union(list1, list2, false);
    }

    /**
     * 并集  去重
     *
     * @param list1
     * @param list2
     * @param distinct
     * @param <T>
     * @return
     */
    public static <T> List<T> union(List<T> list1, List<T> list2, boolean distinct) {
        if (list1 == null || list1.size() == 0) {
            return list2;
        }
        if (list2 == null || list2.size() == 0) {
            return list1;
        }

        List<T> all = new ArrayList<>(list1);
        all.addAll(list2);
        if (distinct) {
            return all.stream().distinct().collect(Collectors.toList());
        }
        return all;
    }
}
